#pragma once

class span {
public:
	int first;
	int last;
public:
	span()
		{ }
	span(int _first, int _last)
		: first(_first), last(_last) { }
	int size() const
		{ return last - first; }
	bool empty() const
		{ return size() == 0; }
	bool valid() const
		{ return first <= last; }
	int bound(int v) const
		{ return (v < first) ? first : ((v > last - 1) ? last - 1 : v); }
	bool operator == (const span & s) const
		{ return first == s.first && last == s.last; }
	bool operator != (const span & s) const
		{ return !operator == (s); }
	bool inside(int t) const
		{ return t >= first && t < last; }
	bool inside(const span & s) const
		{ return s.first >= first && s.last <= last; }
public:
	span & offset(int d) {
		first += d;
		last += d;
		return * this;
	}
	span biasing(int d) const
		{ return span(*this).offset(d); }
	///if the spans are not intersecting, then resulting span will be invalid.
	///Note: compare similarity of  intersect(...) and unite(...)
	span & intersect(const span & s) {
		if (first < s.first)
			first = s.first;
		if (last > s.last)
			last = s.last;
		return * this;
	}
	span intersection(const span & s) const
		{ return span(*this).intersect(s); }
	bool intersecting(const span & s) const
		{ return intersection(s).valid(); }
	span & unite(const span & s) {
		if (first > s.first)
			first = s.first;
		if (last < s.last)
			last = s.last;
		return * this;
	}
	span uniting(const span & s) const
		{ return span(*this).unite(s); }
};